﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Configuration;
using System.IO.Ports;
using System.IO;
using System.Threading;
using iRemoteMulti.Class;
using iRemoteMulti.Forms;

namespace iRemoteMulti
{
    public partial class iRemote : Form
    {

        public static int channel_count = 3;//三通道
        public static SerialPort[] ports = new SerialPort[iRemote.channel_count];//串口对象数组
        public static Channel[] channels = new Channel[iRemote.channel_count];//控制面板数组
        public static String[] channeltoport = new String[iRemote.channel_count];//面板对应的具体串口

        public static List<byte>[] buffer = new List<byte>[iRemote.channel_count];//接收数据缓存数组
        private static object[] lock_buffer = new object[iRemote.channel_count]; //缓冲区写锁
        public Byte[][] back_data_receive = new Byte[iRemote.channel_count][];//上次接收数据
        public Byte[][] new_data_receive = new Byte[iRemote.channel_count][];//最新接收数据

        public static int[] GP = new int[iRemote.channel_count];//GP状态位数组
        public static int[] MPS = new int[iRemote.channel_count];//MPS状态位数组
        public static int[] FPS = new int[iRemote.channel_count];//FPS状态位数组
        public static int[] EN = new int[iRemote.channel_count];//EN状态位数组
        public static int[] RESTP = new int[iRemote.channel_count];//RESTP状态位数组
        public static int[] REMOTE = new int[iRemote.channel_count];//REMOTE状态位数组
        public static int[] SPA_DPA = new int[iRemote.channel_count];//SPA_DPA状态位数组
        public static int[] key_checked = new int[iRemote.channel_count];//key是否验证成功
        public static string[] key = new string[iRemote.channel_count];//key数组

        public static int[] is_leave_time = new int[iRemote.channel_count];//串口断开连接计数器

        public int[] receive_data_count = new int[iRemote.channel_count]; //打开串口接收数据计数（数组）
        public Boolean[] status_ready_init = new Boolean[iRemote.channel_count]; //打开串口接收数据计数（数组）
        public bool[] listening = new bool[iRemote.channel_count];//是否没有执行完invoke相关操作（数组）   
        public bool[] is_closing = new bool[iRemote.channel_count];//是否正在关闭串口，执行Application.DoEvents，并阻止再次invoke（数组）

        public static List<byte[]>[] must_need_to_send = new List<byte[]>[iRemote.channel_count];//发送（操作+数据）缓冲
        public static List<byte>[] operation_need_to_send = new List<byte>[iRemote.channel_count];//发送操作缓冲

        public static DateTime[] gain_send_time = new DateTime[iRemote.channel_count];
        public static double[] gain_send_value = new double[iRemote.channel_count];

        public String record_folder_path;//日志文件记录总路径
        public FileStream record_file_stream;//日志记录文件流
        public String record_file_path; //日志文件记录为准

        public static int current_index = 0; //当前选项页
        public static int receive_data_length = 26; //数据接收长度

        public iRemote()
        {
            InitializeComponent();
        }

        /*
          * 保存配置
          */
        public static void saveConfig(string key, string value)
        {

            /*
             * 运行时配置文件修改
             */
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
            if (config.AppSettings.Settings[key] != null)
            {
                //修改配置
                config.AppSettings.Settings[key].Value = value;
            }
            else
            {
                config.AppSettings.Settings.Add(key, value);
            }
            //保存配置
            config.Save(ConfigurationSaveMode.Modified);
            //更新配置
            ConfigurationManager.RefreshSection("appSettings");

        }

        /*
         * 重置串口配置
         */
        public static void resetPort()
        {
            /*
             * 软件原始配置
             */
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = System.Windows.Forms.Application.StartupPath + @"\\App.config";
            Configuration config_real = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

            /*
             * 软件当前配置
             */
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            /*
             * 读取原始配置到现有配置中
             */
            config.AppSettings.Settings["PortName"].Value = config_real.AppSettings.Settings["PortName"].Value;
            config.AppSettings.Settings["BaudRate"].Value = config_real.AppSettings.Settings["BaudRate"].Value;
            config.AppSettings.Settings["DataBits"].Value = config_real.AppSettings.Settings["DataBits"].Value;
            config.AppSettings.Settings["StopBits"].Value = config_real.AppSettings.Settings["StopBits"].Value;
            config.AppSettings.Settings["Parity"].Value = config_real.AppSettings.Settings["Parity"].Value;

            /*
             * 保存原始配置到现有配置中
             */
            config.Save(ConfigurationSaveMode.Modified);

            //更新配置
            ConfigurationManager.RefreshSection("appSettings");
        }

        /*
         * 重置数据收发配置
         */
        public static void resetDataSend()
        {
            /*
             * 软件原始配置
             */
            ExeConfigurationFileMap fileMap = new ExeConfigurationFileMap();
            fileMap.ExeConfigFilename = System.Windows.Forms.Application.StartupPath + @"\\App.config";
            Configuration config_real = ConfigurationManager.OpenMappedExeConfiguration(fileMap, ConfigurationUserLevel.None);

            /*
             * 软件当前配置
             */
            Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

            /*
             * 读取原始配置到现有配置中
             */
            config.AppSettings.Settings["SendInterval"].Value = config_real.AppSettings.Settings["SendInterval"].Value;
            config.AppSettings.Settings["ReceiveTimeout"].Value = config_real.AppSettings.Settings["ReceiveTimeout"].Value;

            /*
             * 保存原始配置到现有配置中
             */
            config.Save(ConfigurationSaveMode.Modified);

            //更新配置
            ConfigurationManager.RefreshSection("appSettings");
        }

        /*
       * 发送数据到串口
       */
        public static void sendDataToPort(Byte operation, Double data, int index)
        {
            if (iRemote.channels[index].timer3.Enabled && iRemote.channels[index].timer3.Interval <= 333)
            {
                if (operation == 0xC5)
                {
                    Byte[] send_data_bytes = DataFormat.getSendData(operation, data);
                    must_need_to_send[index].Add(send_data_bytes);
                }
                else
                {
                    if (!operation_need_to_send[index].Contains(operation))
                    {
                        operation_need_to_send[index].Add(operation);
                    }
                }
            }
            else
            {
                Byte[] send_data_bytes = DataFormat.getSendData(operation, data);
                iRemote.onlySendDataToPort(send_data_bytes, index);
            }
        }

        /*
         * 单纯发送固定格式数据到串口
         */
        public static void onlySendDataToPort(Byte[] send_data_bytes, int index)
        {
            if (iRemote.ports[index].IsOpen)
            {
                iRemote.ports[index].Write(send_data_bytes, 0, send_data_bytes.Length);
            }
        }

        /*
        * 定时发送数据到串口
        */
        public static void circularSendDataToPort(Byte operation, Double data, int index)
        {
            if (must_need_to_send[index].Count > 0)
            {
                Byte[] send_data_bytes = must_need_to_send[index][0];
                iRemote.onlySendDataToPort(send_data_bytes, index);
                must_need_to_send[index].RemoveAt(0);
                gain_send_time[index] = DateTime.Now;
                byte[] need_data = new byte[2];
                Array.Copy(send_data_bytes, 3, need_data, 0, 2);
                gain_send_value[index] = DataFormat.data_Calculation(need_data);
            }
            else if (operation_need_to_send[index].Count > 0)
            {
                Byte operation_other = operation_need_to_send[index][0];
                Byte[] send_data_bytes = DataFormat.getSendData(operation_other, -1);
                iRemote.onlySendDataToPort(send_data_bytes, index);
                operation_need_to_send[index].RemoveAt(0);
            }
            else
            {
                Byte[] send_data_bytes = DataFormat.getSendData(operation, data);
                iRemote.onlySendDataToPort(send_data_bytes, index);
            }
        }


    }
}
